﻿using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TimeSyncUtil;

namespace TimeSyncServer
{
    public partial class ServerForm : Form
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(ServerForm));

        public int NtpServerPort = 0;

        public string NtpServerAddress = "";

        private NtpServer _server;

        public ServerForm()
        {
            InitializeComponent();
            int.TryParse(ConfigurationManager.AppSettings["NtpServerPort"], out NtpServerPort);
            NtpServerAddress = ConfigurationManager.AppSettings["NtpServerAddress"];
            this.WarnClose();
            this.BindNotifyIcon(时间同步工具, false);
        }

        private void ServerForm_Load(object sender, EventArgs e)
        {
            ServerAddressTxtBox.Text = NtpServerAddress;
            ServerPortTxtBox.Text = NtpServerPort.ToString();
            dataGridView1.Rows.Clear();
            StartListen();
        }

        private void StartListen()
        {
            Task.Run(() =>
            {
                _server = new NtpServer(NtpServerAddress, NtpServerPort);
                _server.LogUpdateInfo += AppendTxt;
                _server.LogUpdateError += AppendErrorTxt;
                _server.LogUpdateDebug += log.Debug;
                _server.NtpReceiveInfoUpdate += ReceiveInfoUpdate;
                try
                {
                    AppendTxt($"正在开启ntp监听服务，{NtpServerAddress}:{NtpServerPort}");
                    _server.Start();
                }
                catch (Exception ex)
                {
                    AppendErrorTxt($"服务端程序异常,错误原因:{ex.Message}-{ex.StackTrace};");
                }
                finally
                {
                    _server.Stop();
                    _server.LogUpdateInfo -= AppendTxt;
                    _server.LogUpdateError -= AppendErrorTxt;
                    _server.LogUpdateDebug -= log.Debug;
                    _server.NtpReceiveInfoUpdate -= ReceiveInfoUpdate;
                }
            });
        }

        private void AppendTxt(string str)
        {
            log.Info(str);
            BeginInvoke(new Action(() =>
            {
                richTextBox1.AppendText($"{DateTime.Now.ToString()} {str}\n");
            }));
        }

        private void AppendErrorTxt(string str)
        {
            log.Error(str);
            BeginInvoke(new Action(() =>
            {
                richTextBox1.AppendText($"{DateTime.Now.ToString()} {str}\n");
            }));
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            int maxLine = 100;//最大显示行数
            if (richTextBox1.Lines.Length > maxLine)
            {
                int curLines = richTextBox1.Lines.Length - maxLine;
                string[] lines = richTextBox1.Lines;
                Array.Copy(lines, curLines, lines, 0, maxLine);
                Array.Resize(ref lines, maxLine);
                richTextBox1.Lines = lines;
            }
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.ScrollToCaret();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            NtpServerAddress = ServerAddressTxtBox.Text;
            int.TryParse(ServerPortTxtBox.Text, out NtpServerPort);
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings["NtpServerPort"].Value = NtpServerPort.ToString();
            config.AppSettings.Settings["NtpServerAddress"].Value = NtpServerAddress;
            config.Save();
            AppendTxt($"服务端信息已更新{NtpServerAddress}:{NtpServerPort.ToString()}");
            if (_server != null)
            {
                _server.Stop();
            }
            StartListen();

        }

        private void ReceiveInfoUpdate(NtpReceiveInfo receiveInfo)
        {

            BeginInvoke(new Action(() =>
            {
                // 找是否存在相等的一列
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells.Count > 0 && row.Cells[0].Value != null && row.Cells[0].Value.Equals(receiveInfo.RequestAddress.ToString()))
                    {
                        UpdateRow(row, receiveInfo);
                        return;
                    }
                }
                dataGridView1.Rows.Add();
                UpdateRow(dataGridView1.Rows[dataGridView1.Rows.Count - 1], receiveInfo);
            }));

        }

        private void UpdateRow(DataGridViewRow row, NtpReceiveInfo receiveInfo)
        {
            row.Cells[0].Value = receiveInfo.RequestAddress;
            if (receiveInfo.OriginTime.TryGet(out var originTime))
            {
                row.Cells[1].Value = originTime.ToLocalTime().ToNtpTimeStr().ToString();
            }
            else
            {
                row.Cells[1].Value = "未解析";
            }
            if (receiveInfo.ResponseTime.TryGet(out var responseTime))
            {
                row.Cells[2].Value = responseTime.ToLocalTime().ToNtpTimeStr().ToString();
            }
            else
            {
                row.Cells[2].Value = "未响应";
            }
            row.Cells[3].Value = $"{DateTime.Now.ToShortTimeString()} {receiveInfo.CurrentState.ToString()}";
        }

        private void ServerForm_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.时间同步工具.ShowBalloonTip(1000);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();
            richTextBox1.Clear();
        }
    }
}
